package com.zzj.handle;

import com.zzj.base.Result;
import com.zzj.base.ResultCode;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.xml.bind.ValidationException;
import java.util.stream.Collectors;

@RestControllerAdvice
public class RestExceptionHandler {
  /**
   * 默认全局异常处理。
   *
   * @param e the e
   * @return Result
   */
  @ExceptionHandler(Exception.class)
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  public Result<String> exception(Exception e) {
    return Result.error(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    // return Result.error(Integer.parseInt(e.getMessage().split(" ")[0]),
    // e.getMessage());
  }

  @ExceptionHandler(value = { BindException.class, ValidationException.class, MethodArgumentNotValidException.class })
  public Result<String> handleValidatedException(Exception e) {
    Result<String> resp = null;

    if (e instanceof MethodArgumentNotValidException) {
      // BeanValidation exception
      MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
      resp = Result.error(ResultCode.PARAM_ERROR.getCode(),
          ResultCode.PARAM_ERROR.getMsg() + ":" + ex.getBindingResult().getAllErrors().stream()
              .map(ObjectError::getDefaultMessage)
              .collect(Collectors.joining("; ")));
    } else if (e instanceof ConstraintViolationException) {
      // BeanValidation GET simple param
      ConstraintViolationException ex = (ConstraintViolationException) e;
      resp = Result.error(
          ex.getConstraintViolations().stream()
              .map(ConstraintViolation::getMessage)
              .collect(Collectors.joining("; ")));
    } else if (e instanceof BindException) {
      // BeanValidation GET object param
      BindException ex = (BindException) e;
      resp = Result.error(
          ex.getAllErrors().stream()
              .map(ObjectError::getDefaultMessage)
              .collect(Collectors.joining("; ")));
    }
    assert resp != null;
    return resp;
  }
}
